﻿using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework.Content;

namespace SoulDoorEngine.Framework.Services
{
    public class SEContentManager : ContentManager
    {
        private bool _PreserveAssets = true;
        private List<IDisposable> _Disposable = new List<IDisposable>();
        private Dictionary<string, object> _Loaded = new Dictionary<string, object>();

        /// <summary>
        /// 已加载资源列表
        /// </summary>
        private Dictionary<string,object> Loaded
        {
            get { return _Loaded; }
            set { _Loaded = value; }
        }
        
        /// <summary>
        /// 资源分配方式列表
        /// </summary>
        private List<IDisposable> Disposable
        {
            get { return _Disposable; }
            set { _Disposable = value; }
        }
        
        /// <summary>
        /// 是否应当保留已经加载的项目以防止重复加载，但在加载诸如特效的时候会出现问题
        /// </summary>
        public bool PreserveAssets
        {
            get { return _PreserveAssets; }
            set { _PreserveAssets = value; }
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="serviceProvider">serviceProvider实例</param>
        public SEContentManager(IServiceProvider serviceProvider)
            : base(serviceProvider)
        {
        }

        /// <summary>
        /// 重载Load函数
        /// </summary>
        /// <typeparam name="T">欲获取资源类型</typeparam>
        /// <param name="assetName">资源类型名称</param>
        /// <returns></returns>
        public override T Load<T>(string assetName)
        {
            T result = this.ReadAsset<T>(assetName, this.RecordIDisposable);

            if (this.PreserveAssets && !this.Loaded.ContainsKey(assetName))
            {
                this.Loaded.Add(assetName, result);
            }

            return result;
        }

        //记录资源分配方式
        void RecordIDisposable(IDisposable asset)
        {
            if (this.PreserveAssets)
            {
                this.Disposable.Add(asset);
            }
        }

        /// <summary>
        /// 卸载所有资源
        /// </summary>
        public override void Unload()
        {
            //释放所有可释放的资源
            foreach (IDisposable item in this.Disposable)
            {
                item.Dispose();
            }

            //清除所有资源
            this.Loaded.Clear();
            this.Disposable.Clear();
        }

        /// <summary>
        /// 释放特定的资源
        /// </summary>
        /// <param name="assetName">资源类型名称</param>
        public void Unload(string assetName)
        {
            if (this.Loaded.ContainsKey(assetName))
            {
                //该资源已被加载并且在资源分配方式列表中存在
                if (this.Loaded[assetName] is IDisposable
                    && this.Disposable.Contains((IDisposable)this.Loaded[assetName]))
                {
                    IDisposable obj = this.Disposable[
                        this.Disposable.IndexOf((IDisposable)this.Loaded[assetName])];

                    obj.Dispose();

                    this.Disposable.Remove(obj);
                }

                this.Loaded.Remove(assetName);
            }
        }
    }
}
